| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 |
1×
1×
1×
1×
36×
18×
18×
18×
2×
19×
2×
14×
2×
18×
2×
20×
2×
37×
2×
8×
8×
8×
2×
14×
15×
2×
14×
2×
4×
8×
2×
14×
14×
14×
14×
14×
14×
5×
9×
2×
9×
9×
19×
17×
2×
9×
9×
9×
9×
9×
3×
3×
2×
1×
6×
9×
1×
9×
9×
9×
| import { Battle, Game, Suit, Card, PlayersBid, Player, TrumpAnnouncement, CardPattern } from '../game.interfaces';
import { getNextTurn, getPlayerById, getPlayerTotalPoints } from './players.helpers';
import * as _ from 'lodash';
import { getHighestBid } from './bid.helpers';
import { getPointsByCard, getTrumpPointsBySuit, areCardsEqual, getCardsByColor, getCardWithHighestRank, cardsWithSpecificColorExists, toCard } from './cards.helpers';
export function getNextTrickTurn(state: Game, Eplayer: string = state.battle.leadPlayer): string {
const gamePlayers = state.players;
const { battle } = state;
return _.reduce(battle.trickCards, (nextPlayer) => getNextTurn(gamePlayers, nextPlayer), player);
}
export function getTrumpSuit(battle: Battle): Suit | null {
return battle.trumpAnnouncements.length > 0 ? battle.trumpAnnouncements[0].suit : null;
}
export function isTrumpAnnounced(battle: Battle): boolean {
return !!getTrumpSuit(battle);
}
export function isTableEmpty(battle: Battle): boolean {
return battle.trickCards.length === 0;
}
export function getLeadCard(battle: Battle): CardPattern {
return battle.trickCards[0];
}
export function getCardSuit(card: CardPattern): Suit {
return toCard(card).suit;
}
export function roundPoints(points: number): number {
const minor = (points % 10);
const major = points - minor;
return minor >= 5 ? major + 10 : major;
}
export function calculateTrumpPointsForPlayer(state: Game, player: string): number {
return _.chain(state.battle.trumpAnnouncements)
.filter((trumpAnnouncement: TrumpAnnouncement) => trumpAnnouncement.player === player)
.map('suit')
.map(getTrumpPointsBySuit)
.sum()
.value();
}
export function calculateCardPointsForPlayer(state: Game, player: string): number {
return _.chain(state.battle.wonCards[player])
.map(toCard)
.map(getPointsByCard)
.sum()
.value();
}
export function getTotalWonCards(state: Game): number {
return _.reduce(state.battle.wonCards, (totalCards, cards) => {
return totalCards + cards.length;
}, 0);
}
export function calculatePointsByPlayer(state: Game, player: string): number {
const {player: leadPlayer, bid: leadBidValue}: PlayersBid = getHighestBid(state.bid);
const playerPoints = getPlayerTotalPoints(getPlayerById(state.players, player));
const trumpPoints = calculateTrumpPointsForPlayer(state, player);
const cardPoints = calculateCardPointsForPlayer(state, player);
const totalPoints = trumpPoints + cardPoints;
if (leadPlayer === player) {
return (totalPoints >= leadBidValue) ? leadBidValue : -leadBidValue
} else {
return playerPoints >= state.settings.barrelPointsLimit ? 0 : roundPoints(totalPoints);
}
}
export function getPlayerByTrickCard(trickCard: CardPattern, state: Game): string {
const { battle: { leadPlayer, trickCards }, players } = state;
return _.chain(trickCards)
.dropRightWhile(card => !areCardsEqual(card, trickCard))
.reduce((player: string) => player ? getNextTurn(players, player) : leadPlayer, null)
.value();
}
export function getTrickWinner(state: Game): string {
const { battle } = state;
const { trickCards } = battle;
const leadCard: CardPattern = getLeadCard(battle);
let winnerPlayerId = null;
if(isTrumpAnnounced(battle)) {
const trumpSuit: Suit = getTrumpSuit(battle);
if (cardsWithSpecificColorExists(trickCards, trumpSuit)) {
matchBySuit(trumpSuit);
} else {
//no trump cards taking part in the trick, so ordinary color matching flow:
matchBySuit(getCardSuit(leadCard));
}
} else {
matchBySuit(getCardSuit(leadCard));
}
return winnerPlayerId;
function matchBySuit(suit: Suit) {
const cardsMatchedByColor = getCardsByColor(trickCards, getCardSuit(leadCard));
const highestRankedCard = getCardWithHighestRank(cardsMatchedByColor);
winnerPlayerId = getPlayerByTrickCard(highestRankedCard, state);
}
} |